﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RestService
{
    public class Matrix
    {
        public static double[,] CongMaTran(double[,] A, double[,] B)
        {
            int soHang = A.GetLength(0);
            int soCot = A.GetLength(1);

            double[,] C = new double[soHang, soCot];

            for (int i = 0; i < soHang; i++)
            {
                for (int j = 0; j < soCot; j++)
                {
                    C[i, j] = A[i, j] + B[i, j];
                }
            }

            return C;
        }

        public static double[,] TruMaTran(double[,] A, double[,] B)
        {
            int soHang = A.GetLength(0);
            int soCot = A.GetLength(1);

            double[,] C = new double[soHang, soCot];

            for (int i = 0; i < soHang; i++)
            {
                for (int j = 0; j < soCot; j++)
                {
                    C[i, j] = A[i, j] - B[i, j];
                }
            }

            return C;
        }
        public static double[,] NhanMaTran(double[,] _A, double[,] _B, int _n, int _m, int _r)
        {
            int n, m, r;
            double si;
            n = _n;
            m = _m;
            r = _r;
            double[,] A = new double[n, m];
            double[,] B = new double[m, r];
            double[,] C = new double[n, r];
            A = _A;
            B = _B;
            try
            {
                for (int i = 0; i < n; i++)
                {
                    for (int j = 0; j < r; j++)
                    {
                        si = 0;
                        for (int k = 0; k < m; k++)
                        {
                            si += A[i,k]*B[k,j];
                        }
                        C[i,j] = si;
                    }
                }
            }
            catch (Exception ex) {
                throw ex;
            }
            return C;
        }
        public static double DinhThuc(double[,] A)
        {
            int soHang = A.GetLength(0);
            int soCot = A.GetLength(1);

            double result = 0;
            double det = 0;
            int n = A.GetLength(0);
            if (soHang == 2)
            {
                result = A[0, 0] * A[1, 1] - A[1, 0] * A[0, 1];
            }
            else
            {
                for (int i = 0; i < soHang; i++)
                {
                    double[,] temp = CatMaTran(A, i, 0);
                    det += DinhThuc(temp);
                    result += A[i, 0] * Math.Pow(-1, i) * det;
                }
            }
            return result;
        }

        public static double[,] CatMaTran(double[,] A, int x, int y)
        {
            int soHang = A.GetLength(0);
            int soCot = A.GetLength(1);

            List<double> lst = new List<double>();

            double[,] temp = CopyMaTran(A);
            double[,] ketqua = new double[soHang - 1, soCot - 1];
            for (int i = 0; i < soHang; i++)
            {
                //Lấy 1 dòng ra, trừ dòng x
                if (i != x)
                {
                    //Cắt vị trí y đi
                    for (int j = 0; j < soCot; j++)
                    {
                        if (j != y)
                            lst.Add(A[i, j]);
                    }
                }
            }

            int index = 0;
            for (int i = 0; i < soHang - 1; i++)
            {
                for (int j = 0; j < soCot - 1; j++)
                {
                    ketqua[i, j] = lst[index++];
                }
            }

            return ketqua;
        }

        public static double[,] CopyMaTran(double[,] A)
        {
            int soHang = A.GetLength(0);
            int soCot = A.GetLength(1);

            double[,] temp = new double[soHang, soCot];

            for (int i = 0; i < soHang; i++)
            {
                for (int j = 0; j < soCot; j++)
                {
                    temp[i, j] = A[i, j];
                }
            }

            return temp;
        }
        public static double[,] MatranNghich(double[,] A)
        {
            int soHang = A.GetLength(0);
            int soCot = A.GetLength(1);
            double[,] B = new double[soCot, soHang];
            double C = 1 / DinhThuc(A);
            for (int i = 0; i < soHang; i++)
            {
                for (int j = 0; j < soCot; j++)
                {
                    B[j, i] = C * A[i, j];
                }
            }
            return B;
        }
    }
}
